#include "mainwindowimpl.h"
#include <qwt-qt4/qwt_plot.h>
#include <qwt-qt4/qwt_plot_curve.h>
#include <qwt-qt4/qwt_plot_dict.h>
#include <qwt-qt4/qwt_scale_engine.h>

#define MIN(a,b) (a<b)?a:b
#define MAX(a,b) (a>b)?a:b

void MainWindowImpl::on_but_plot_clicked()
{
    QSqlQuery query;
    QString str;
    double amp,par,paramN;
    QwtPlotCurve *curve[4];
    for (int i=0; i<4; i++) curve[i] = new QwtPlotCurve("curveAFR");
    plotDiag->detachItems(QwtPlotItem::Rtti_PlotCurve,1);
    plotPhase->detachItems(QwtPlotItem::Rtti_PlotCurve,1);
    plotAFR->detachItems(QwtPlotItem::Rtti_PlotCurve,1);
    QVector<double> dataX, dataY[4];
    QColor colors[4]={Qt::red, Qt::blue, Qt::black, Qt::cyan};
    //for (int i=0; i<waveSqlModel->rowCount(); i++)
    int i=0,j=0,count;
    paramN = (param==0 ? boxParamN->value()*(ft.b?ft.b:ft.a) : boxParamN->value());
    if (method==5) paramN=boxParamN->value()*ft.a;
    count=waveSqlModel->rowCount();
    while (i<count)
    {
        do
        {
            query.exec("SELECT * FROM wave WHERE id ="+str.setNum(i+1));
            query.first();	//set position
            par=query.value(9+param).toDouble();
            dataX.append(par);
            //if (metHer->isChecked()) par*=boxGeom_b->value()/boxGeom_a->value();
            //dataParam.append(query.value(9+param).toDouble());
            if (i==0) amp=query.value(32).toDouble();
            //dataDiag.append(pow(query.value(32).toDouble(),2));
            if(query.value(31).toInt()==3) dataY[j].append(pow(query.value(32).toDouble(),2));
            else dataY[j].append(query.value(32).toDouble());
            //dataPhase.append(query.value(33).toDouble());
            //dataAFRx.append(query.value(1).toDouble());
            //dataAFRy.append(query.value(2).toDouble());
            i++;
        }
        while (par!=paramN);
        curve[j]->setData(dataX,dataY[j]);
        curve[j]->setPen(QPen(colors[j]));
        curve[j]->attach(plotDiag);
        j++;
    }
    //curveAmp->setData(dataParam,dataDiag);
    //curveAmp->attach(plotDiag);
    //curvePhase->setData(dataParam,dataPhase);
    //curvePhase->attach(plotPhase);
//    curvePhase->setStyle(QwtPlotCurve::Dots);
    //curveAFR->setData(dataAFRx,dataAFRy);
    //curveAFR->attach(plotAFR);
    plotDiag->replot();
    plotPhase->replot();
    plotAFR->replot();
    QImage image(plotDiag->sizeHint(),QImage::Format_ARGB32_Premultiplied);
    image.fill(NULL);
    QPainter painter(&image);
    QRect rect(QPoint(0,0),plotDiag->sizeHint());
    plotDiag->print(&painter,rect);
    image.save("graph.png");
}

void MainWindowImpl::on_but_gauss_clicked()
{
    QSqlQuery query;
    QString str;
    double amp=1;
    Gauss aprx;
    aprx.printGauss(textAprx);
    QwtPlotCurve *curve = new QwtPlotCurve("curve1");
    QVector<double> dataParam(0),dataDiag(0);
    for (int i=0; i<waveSqlModel->rowCount(); i++)
    {
        query.exec("SELECT * FROM wave WHERE id ="+str.setNum(i+1));
        query.first();	//set position
        dataParam.append(query.value(9+param).toDouble());
        if (i==0) amp=query.value(32).toDouble();
        dataDiag.append(aprx.getValue(dataParam.last())*amp);
    }
    curve->setData(dataParam,dataDiag);
    curve->attach(plotDiag);
//    curve->setStyle(QwtPlotCurve::Dots);
    plotDiag->replot();
}

bool MainWindowImpl::on_but_debug_clicked()
{
    plotDiag->detachItems(QwtPlotItem::Rtti_PlotCurve,0);
    plotPhase->detachItems(QwtPlotItem::Rtti_PlotCurve,0);
    plotAFR->detachItems(QwtPlotItem::Rtti_PlotCurve,0);
    QString str;
    int NPt=200;	//NPt: number of points through teta; sopr: sign of image patr
    double Begin,Step;
    Begin=boxBegin->value();
    Step=(boxEnd->value()-Begin)/NPt;
    Structure *toFt;
    toFt=&ft;
    initCalc(); //Initialization
    //! on_but_printParam_clicked(); //print
    QwtPlotCurve *curve[4];
    for (int i=0; i<4; i++) curve[i]= new QwtPlotCurve("curve"+str.setNum(i));
    QVector<double> dataX[4],dataY[4];
    progress_int->setMaximum(NPt);
    //begin of evaluating
    gsl_complex gslBuf;
    double k;
    if(method==3)
    {
        if (param!=1)
        {
            QMessageBox::information(0, qApp->tr("Diagram"), qApp->tr("Please, choose 'Fi' as "
                                                                      "the variable parameter "), QMessageBox::Close);
            return 0;
        }
        k=Begin-Step;
        for (int i=0; i<NPt; i++)
        {
            k+=Step;
            toFt->k=k/ft.b;
            Vainshtein vt(toFt);
            //dataX[0].append(k);
            //GSL_SET_COMPLEX(&gslBuf,__real__(vt.Delta),__imag__(vt.Delta));
            vt.coeffs(progress_int);
            GSL_SET_COMPLEX(&gslBuf,__real__(vt.Rln[0]),__imag__(vt.Rln[0]));
            //dataY[0].append(__imag__(vt.Rln[0]));
            if(GSL_REAL(gslBuf)!=0) { dataY[0].append(gsl_complex_abs(gslBuf)); dataX[0].append(k); text_cp->append(str.setNum(dataY[0].last()));}
            GSL_SET_COMPLEX(&gslBuf,__real__(vt.Rln[1]),__imag__(vt.Rln[1]));
            if(GSL_REAL(gslBuf)!=0) { dataY[1].append(gsl_complex_abs(gslBuf)); dataX[1].append(k); }
            GSL_SET_COMPLEX(&gslBuf,__real__(vt.Tln[0]),__imag__(vt.Tln[0]));
            if(GSL_REAL(gslBuf)!=0) { dataY[2].append(gsl_complex_abs(gslBuf)); dataX[2].append(k); }
            GSL_SET_COMPLEX(&gslBuf,__real__(vt.Tln[1]),__imag__(vt.Tln[1]));
            if(GSL_REAL(gslBuf)!=0) { dataY[3].append(gsl_complex_abs(gslBuf)); dataX[3].append(k); }
            //GSL_SET_COMPLEX(&gslBuf,__real__(vt.Rln[0]),__imag__(vt.Rln[0]));
            //dataY[2].append(gsl_complex_abs(gslBuf));
            //dataY[1].append(gsl_complex_arg(gslBuf));
            //dataY[0].append(vt.OmegaT(k)/(pow(k,2)-pow(vt.MMN[0],2)));
            //text_cp->append(str.setNum(dataY[0].last()));
            QApplication::processEvents();
        }
//        Vainshtein vt(toFt);
//        gsl_complex gslBuf;
//        for (int i=0; i<NPt; i++)
//        {
////            k=(double)i*atan(10000)/NPt;
////            dataX[0].append(k);
////            dataY[2].append(vt.OmegaT(sqrt(pow(4,2)+pow(tan(k),2)))/((16-pow(vt.MMN[0],2))*pow(cos(k),2)+pow(sin(k),2)));
//            k=(double)i*50/NPt;
//            dataX[0].append(k);
//            dataY[1].append(vt.OmegaT(sqrt(pow(4,2)+pow(k,2)))/(pow(4,2)-pow(vt.MMN[0],2)+pow(k,2)));
//            dataY[2].append(vt.Omega(sqrt(pow(4,2)+pow(k,2))));
//            GSL_SET_COMPLEX(&gslBuf,vt.besselS(vt.mI,sqrt(pow(4,2)+pow(k,2))),vt.mI/sqrt(pow(4,2)+pow(k,2))*gsl_sf_bessel_Yn(vt.mI,sqrt(pow(4,2)+pow(k,2)))-gsl_sf_bessel_Yn(vt.mI+1,sqrt(pow(4,2)+pow(k,2))));
//            dataY[0].append(gsl_complex_arg(gslBuf));
//        }
        curve[0]->setData(dataX[0],dataY[0]);
        curve[0]->setPen(QPen(Qt::black));
        curve[0]->attach(plotDiag);
        //curve[0]->attach(plotPhase);
        curve[1]->setData(dataX[1],dataY[1]);
        curve[1]->setPen(QPen(Qt::blue));
        curve[1]->attach(plotDiag);
        curve[2]->setData(dataX[2],dataY[2]);
        curve[2]->setPen(QPen(Qt::red));
        //curve[2]->attach(plotDiag);
        curve[2]->attach(plotDiag);
        curve[3]->setData(dataX[3],dataY[3]);
        curve[3]->setPen(QPen(Qt::magenta));
        curve[3]->attach(plotDiag);
        plotDiag->setAxisScaleEngine(QwtPlot::yLeft,new QwtLog10ScaleEngine);
        //plotDiag->setAxisScale(QwtPlot::yLeft,0.0001,1);
        plotDiag->replot();
        plotAFR->replot();
        plotPhase->replot();
        text_cp->append(str);
        //vt.coeffs(progress_int);
        QImage image(plotDiag->sizeHint(),QImage::Format_ARGB32_Premultiplied);
        image.fill(NULL);
        QPainter painter(&image);
        QRect rect(QPoint(0,0),plotDiag->sizeHint());
        plotDiag->print(&painter,rect);
        image.save("graph.png");
    }
    return 1;
}

bool MainWindowImpl::on_but_dediff_clicked()
{
    plotDiag->detachItems(QwtPlotItem::Rtti_PlotCurve,0); // clear
    plotPhase->detachItems(QwtPlotItem::Rtti_PlotCurve,0);
    plotAFR->detachItems(QwtPlotItem::Rtti_PlotCurve,0);
    QString str;
    QwtPlotCurve *curve[3];
    for (int i=0; i<3; i++) curve[i]= new QwtPlotCurve("curve"+str.setNum(i));
    QVector<double> dataX[3],dataY[3];
    Structure *toFt;
    toFt=&ft;
    if(method==4)
    {
        initCalc(); //Initialization
        int NPt=100;	//NPt: number of points
        double Begin = boxBegin->value();
        double Step = (boxEnd->value()-Begin)/NPt;
        double k = Begin-Step;

        for (int i=0; i<NPt; i++)
        {
            k+=Step;
            dataX[1].append(k);
            text_cp->append("k=\t"+str.setNum(k));
            toFt->k=k/ft.a;
            Diffraction dt(toFt);
            dt.stepByStep(text_cp);
            dataY[1].append(gsl_complex_abs(dt.Refract));
            dt.matrix(text_cp);
            dataY[0].append(gsl_complex_abs(dt.Refract));
            dt.approximation(text_cp);
            dataY[2].append(gsl_complex_abs(dt.Refract));
            //dataY[1].append(gsl_complex_arg(dt.Refract));
            // dataY[1].append(180+refract[2]/M_PI*180);
            QApplication::processEvents();
        }
        curve[0]->setData(dataX[1],dataY[0]);
        curve[0]->setPen(QPen(Qt::blue));
        curve[0]->attach(plotDiag);
        curve[1]->setData(dataX[1],dataY[1]);
        curve[1]->setPen(QPen(Qt::red));
        curve[1]->attach(plotDiag);
        curve[2]->setData(dataX[1],dataY[2]);
        curve[2]->setPen(QPen(Qt::black));
        curve[2]->attach(plotDiag);
        //curve[2]->attach(plotDiag);
        plotPhase->setAxisScaleEngine(QwtPlot::yLeft,new QwtLog10ScaleEngine); // logarithm
        plotDiag->replot();
        plotPhase->replot();
        plotAFR->replot();
        QImage image(plotDiag->sizeHint(),QImage::Format_ARGB32_Premultiplied);
        image.fill(NULL);
        QPainter painter(&image);
        QRect rect(QPoint(0,0),plotDiag->sizeHint());
        plotDiag->print(&painter,rect);
        image.save("graph.png");
    }
    return 1;
}

bool MainWindowImpl::on_but_Export_clicked()
{
    QString names[7];
    QFile *inputs[7];
    QTextStream *stream[7];
    QFileInfo *file;
    QDir dir;
    names[0]=QFileDialog::getOpenFileName(this,"Select Parameters File",".","Text files (*.txt)");
    inputs[0] = new QFile(names[0]);
    stream[0] = new QTextStream(inputs[0]);
    file = new QFileInfo(*inputs[0]);
    dir.setCurrent(file->absolutePath());
    names[1]="Dec_X.txt";    names[2]="Dec_Y.txt";
    names[3]="Dec_Re.txt";    names[4]="Dec_Im.txt";    names[5]="Dec_Abs.txt";    names[6]="Dec_Arg.txt";
    for (int i=1; i<7; i++)
    {
        inputs[i] = new QFile(names[i]);
        inputs[i]->open(QIODevice::ReadOnly);
        stream[i] = new QTextStream(inputs[i]);
    }
    bool flag=0;
    int j=0;
    double buf[6];
    while(!flag)
    {
        for (int i=1; i<7; i++)
            buf[i-1]=stream[i]->readLine().toDouble();
        if(!buf[4]) flag=1;
        else
        {
            waveSqlModel->insertRows(j,1);
            waveSqlModel->setData(waveSqlModel->index(j,Base.key("q1")),buf[0]);
            waveSqlModel->setData(waveSqlModel->index(j,Base.key("q2")),buf[1]);
            waveSqlModel->setData(waveSqlModel->index(j,Base.key("realE")),buf[2]);
            waveSqlModel->setData(waveSqlModel->index(j,Base.key("imagE")),buf[3]);
            waveSqlModel->setData(waveSqlModel->index(j,Base.key("Amp")),buf[4]);
            waveSqlModel->setData(waveSqlModel->index(j,Base.key("Arg")),buf[5]);
            waveSqlModel->submitAll();
            j++;
        }
    }
    waveTable->resizeColumnsToContents();
    return 1;
}
